﻿using SD.Infrastructure.Repository.EntityFrameworkCore;
using SlamDunk.MES.Domain.Entities.ExecutionContext;
using SlamDunk.MES.Domain.Entities.ResourceContext;
using SlamDunk.MES.Domain.IRepositories.Interfaces.ExecutionContext;
using SlamDunk.MES.ReportView.Models;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SlamDunk.MES.Repository.Implements.ExecutionContext
{
    /// <summary>
    /// 工单实际人员仓储实现
    /// </summary>
    public class WorkOrderActualPersonRepository : EFEntityRepositoryProvider<WorkOrderActualPerson>, IWorkOrderActualPersonRepository
    {
        #region # 获取工单实际人员列表 —— ICollection<WorkOrderActualPerson> Find(Guid workOrderId)
        /// <summary>
        /// 获取工单实际人员列表
        /// </summary>
        /// <param name="workOrderId">工单Id</param>
        /// <returns>工单实际人员列表</returns>
        public ICollection<WorkOrderActualPerson> Find(Guid workOrderId)
        {
            IQueryable<WorkOrderActualPerson> actualPersons = base.Find(x => x.WorkOrder.Id == workOrderId);

            return actualPersons.ToList();
        }
        #endregion

        #region # 获取作业计划人员概要列表 —— ICollection<PersonSummaryInfo> GetPersonSummariesByExecutionPlan(...
        /// <summary>
        /// 获取作业计划人员概要列表
        /// </summary>
        /// <param name="executionPlanId">作业计划Id</param>
        /// <returns>人员概要列表</returns>
        public ICollection<PersonSummaryInfo> GetPersonSummariesByExecutionPlan(Guid executionPlanId)
        {
            IQueryable<WorkOrderActualPerson> actualPersonsQueryable = base.Find(x => x.WorkOrder.ExecutionPlanId == executionPlanId);
            IQueryable<Guid> personIds = actualPersonsQueryable.Select(x => x.PersonId).Distinct();

            IList<WorkOrderActualPerson> actualPersons = actualPersonsQueryable.ToList();
            IList<Person> persons = this._dbContext.Set<Person>().Where(x => personIds.Contains(x.Id)).ToList();

            IEnumerable<PersonSummaryInfo> personSummaries =
                from actualPerson in actualPersons
                let person = persons.Single(x => x.Id == actualPerson.PersonId)
                let duration = actualPerson.ActualEndTime - actualPerson.ActualStartTime
                select new PersonSummaryInfo
                {
                    PersonId = person.Id,
                    PersonNo = person.Number,
                    PersonName = person.Name,
                    Manhour = Convert.ToDecimal(duration.TotalHours)
                };

            var personSummaryGroups = personSummaries.GroupBy(x => new
            {
                x.PersonId,
                x.PersonNo,
                x.PersonName
            }).Select(x => new
            {
                x.Key,
                Manhour = x.Any() ? x.Sum(y => y.Manhour) : 0m
            });
            IEnumerable<PersonSummaryInfo> result =
                from personSummaryGroup in personSummaryGroups
                let manhour = personSummaryGroup.Manhour
                select new PersonSummaryInfo
                {
                    PersonId = personSummaryGroup.Key.PersonId,
                    PersonNo = personSummaryGroup.Key.PersonNo,
                    PersonName = personSummaryGroup.Key.PersonName,
                    Manhour = manhour
                };

            return result.ToList();
        }
        #endregion
    }
}
